#include "typedef.h"
#include "queuedef.h"

boolean queue_push(Queue q, QueueNode node)
{
    if(!isQueue(q)){
        return False;
    }
    if(0 == q->num)
    {
        q->first = q->last = node;
        node->prev = node->next = NULL;
    }
    else
    {
        q->last->next = node;
        node->prev = q->last;
        node->next = NULL;
        q->last = node;
    }
    node->queue = CAST_AS(address, q);
    q->num++;
    return True;
}

QueueNode queue_pop(Queue q)
{
    if(0 == q->num)
    {
        return CAST_AS(QueueNode,NULL);
    }
    QueueNode first = q->first;
    QueueNode second = q->first->next;
    q->first = second;
    q->num--;
    if (second)
    {
        second->prev = CAST_AS(QueueNode,NULL);
    }
    else
    {
        q->last = CAST_AS(QueueNode,NULL);
    }
    first->queue = CAST_AS(address, NULL);
    return first;
}

QueueNode queue_popback(Queue q)
{
    if(0 == q->num)
    {
        return CAST_AS(QueueNode,NULL);
    }
    QueueNode last = q->last;
    QueueNode last2 = q->last->prev;
    q->last = last2;
    q->num--;
    last->queue = CAST_AS(address, NULL);
    return last;
}

void queue_init(Queue q)
{
    q->magic = _IS_QUEUE__;
    q->num  = 0;
    q->first = q->last = NULL;
}

boolean queue_is_empty(Queue q)
{
    return CAST_AS(boolean, q->num == 0);
}


boolean queue_remove(Queue q, QueueNode node)
{
    if(node->queue != CAST_AS(address, q))
    {
        return False;
    }
    QueueNode next = node->next;
    QueueNode prev = node->prev;
    if(q->first == node)
    {
        q->first = next;
    }
    else
    {
        prev->next = next;
    }

    if(q->last == node)
    {
        q->last = prev;
    }
    else
    {
        next->prev = prev;
    }

    node->queue = CAST_AS(Queue, NULL);
    node->next = 
    node->prev = CAST_AS(QueueNode, NULL);
    q->num--;
    return True;
}